<?php if (!defined('CORE_DIR')) die('Wrong entry point!');

/* 
 * Copyright 2010 Anton Muraviev a.k.a kuromaisu
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */


Aero::define('GroupFormControl', AS_CLASS);

/* -----------------------------------------------------------------------------
 * Class: GroupFormControl
 * -----------------------------------------------------------------------------
 *
 */
class GroupFormControl extends BaseFormControl
{
	protected $template = null;
	protected $controls = null;
	
	public function __construct($params = array())
	{
		$this->properties = array_merge($this->properties, array('template','controls'));
		
		parent::__construct($params);
	}
	
	protected function _initialize()
	{
		parent::_initialize();
		
		foreach ($this->controls as $name => $data)
		{
			if (!empty($data['multiple']))
			{
				trigger_error('Grouped controls cannot be <var>multple</var>. Only the group control itself can.', E_USER_ERROR);
			}
			
			$sep = Aero::option('form.id_separator','_');
			
			$data['name'] = $this->name.$sep.$name;
			$data['multiple'] = $this->multiple;
			
			$control = isset($data['control']) ? $data['control'] : 'text';
			$this->controls[$name]['__field'] = Aero::load('libs/form_controls/'.$control,$data);
		}
		
		// We shall pass $default onto sub controls and set our own $value from theirs
		if (AeroForm::$submitted)
		{
			$values = array();
			
			foreach ($this->controls as $_name => $_control)
			{
				$values[$_name] = $_control['__field']->value('raw');
			}
			
			reset($values);
			
			if (is_array(current($values)))
			{
				$this->value = array();
				$_values = array();
				
				// We need to revert the nesting order from [control][key] to [key][control]
				foreach ($values as $_control => $_value)
				{
					if (!is_array($_value))
					{
						continue;
					}
					
					foreach ($_value as $__key => $__value)
					{
						$_values[$__key][$_control] = $__value;
					}
				}
				
				// Shall we serialize?
				if (method_exists($this, '_serialize'))
				{
					foreach ($_values as $key => $value)
					{
						$this->value[$key] = $this->_serialize($value);
					}
				}
				else
				{
					$this->value = $_values;
				}
			}
			else
			{
				$this->value = (method_exists($this, '_serialize') ? $this->_serialize($values) : $values);
			}
		}
		
		if (!empty($this->default))
		{
			$this->setDefault($this->default);
		}
		
		if (!is_null($this->template))
		{
			$this->snippets['control'] = $this->template;
		}
		else
		{
			$this->snippets['control'] = '{'.implode('} {',array_keys($this->controls)).'}';
		}
	}
	
	public function setDefault($value)
	{
		parent::setDefault($value);
		
		$_values = array();
		
		if (is_array($this->default))
		{
			if (array_values($this->default) == $this->default)
			{
				foreach ($this->default as $_key => $_value)
				{
					if (is_array($_value))
					{
						foreach ($_value as $control => $value)
						{
							$_values[$control][$_key] = $value;
						}
					}
					else if (method_exists($this,'_unserialize'))
					{
						$values = $this->_unserialize($_value);
						
						foreach ($values as $control => $value)
						{
							$_values[$control][$_key] = $value;
						}
					}
				}
			}
			else
			{
				$_values = $this->default;
			}
		}
		else if (method_exists($this, '_unserialize'))
		{
			$_values = $this->_unserialize($this->default);
		}
		
		foreach ($_values as $control => $default)
		{
			if ($this->controls[$control]['__field'] instanceof BaseFormControl)
			{
				$this->controls[$control]['__field']->setDefault($default);
			}
		}
	}
	
	public function validate()
	{
		$is_group_valid = true;
		
		foreach ($this->controls as $_name => $_control)
		{
			$field =& $_control['__field'];
			$is_group_valid &= $field->validate();
		}
		
		return $is_group_valid;
	}
	
	protected function _modifyVariables(&$vars)
	{
		$sep = Aero::option('form.id_separator','_');
		
		foreach ($this->controls as $name => $data)
		{
			$field =& $this->controls[$name]['__field'];
			$vars[$name] = Aero::option('form.group.before','<span class="item">').$field->render('control');
			
			// FIXME: Display all controls' errors together.
			if (!empty($field->error))
			{
				$vars[$name].= ' '.$field->render('error');
			}
			
			$vars[$name].= Aero::option('form.group.after','</span>');
		}
	}
}